package edu.hawaii.senin.iclouds.simple;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Test;

import edu.hawaii.senin.iclouds.basics.Atom;
import edu.hawaii.senin.iclouds.basics.Molecule;
import edu.hawaii.senin.iclouds.basics.PopulationSimple;
import edu.hawaii.senin.iclouds.basics.ReadConfigException;

/**
 * Tests appropriate coniguration parsing.
 * 
 * @author Pavel Senin.
 * 
 */
public class TestReadAndParseCloudPopulation {

  private static final String configName1 = "config/test_cfg/test002.xml";
  private Cloud testCloud;

  /**
   * Makes testing fixture.
   * 
   * @throws ReadConfigException in case of error.
   * 
   */
  @Before
  public void setUp() throws ReadConfigException {
    this.testCloud = new Cloud();
    CloudParametersMessage cm = new CloudParametersMessage();
    cm.addParameter(CloudParametersMessage.CFGNAME, configName1);
    testCloud.setParameters(cm);
  }

  /**
   * Tests correct variables extraction.
   * 
   */
  @Test
  public void testInitialPopulation() {

    Double sum = 0D;

    PopulationSimple cloudPopulation = testCloud.getCloudPopulation();

    // <atom>
    // <name>H</name>
    // <amu>1.008</amu>
    // <abundance>1.0</abundance>
    // <fraction>0.999</fraction>
    // <type>active</type>
    // </atom>
    Atom hydrogen = (Atom) cloudPopulation.getSpecie("H");
    assertEquals("Testing amu getter", 1.008D, hydrogen.getAmu());
    assertEquals("Testing abundance getter", 1.0D, hydrogen.getAbundance());
    assertEquals("Testing fraction getter", 1.0D, hydrogen.getFraction());
    assertTrue("Testing isActive getter", hydrogen.isActive());
    assertEquals("Test velocities", 497.5287689493952D, hydrogen.getVelocity());
    assertEquals("Testing accretion probability", 0.9129587901527775, hydrogen
        .getAccretionProbability());
    sum += hydrogen.getAccretionProbability();

    // <atom>
    // <name>D</name>
    // <amu>2.04</amu>
    // <abundance>1.0</abundance>
    // <fraction>0.001</fraction>
    // <type>active</type>
    // </atom>
    Atom deuterium = (Atom) cloudPopulation.getSpecie("D");
    assertEquals("Testing amu getter", 2.04D, deuterium.getAmu());
    assertEquals("Testing fraction getter", 1.0D, deuterium.getAbundance());
    assertEquals("Testing fraction getter", 0.01D, deuterium.getFraction());
    assertTrue("Testing isActive getter", deuterium.isActive());
    assertEquals("Test velocities", 349.73039682113165D, deuterium.getVelocity());
    assertEquals("Testing accretion probability", 0.009129587901527774, deuterium
        .getAccretionProbability());
    sum += deuterium.getAccretionProbability();

    // <atom>
    // <name>O</name>
    // <amu>16.000</amu>
    // <abundance>3.4E-4</abundance>
    // <fraction>0.99</fraction>
    // <type>active</type>
    // </atom>
    Atom oxygen = (Atom) cloudPopulation.getSpecie("O");
    assertEquals("Testing amu getter", 16.0D, oxygen.getAmu());
    assertEquals("Testing abundance getter", 3.4E-4, oxygen.getAbundance());
    assertEquals("Testing fraction getter", 0.99D, oxygen.getFraction());
    assertTrue("Testing isActive getter", oxygen.isActive());
    assertEquals("Test velocities", 124.87872990920008D, oxygen.getVelocity());
    assertEquals("Testing accretion probability", 0.045856749032795074, oxygen
        
        .getAccretionProbability());
    sum += oxygen.getAccretionProbability();

    // <molecule>
    // <name>O2</name>
    // <amu>32.000</amu>
    // <abundance>3.4E-4</abundance>
    // <fraction>0.01</fraction>
    // <type>passive</type>
    // </molecule>
    Molecule oxygenMolecule = (Molecule) cloudPopulation.getSpecie("O2");
    assertEquals("Testing amu getter", 32.0D, oxygenMolecule.getAmu());
    assertEquals("Testing abundance getter", 3.4E-4, oxygenMolecule.getAbundance());
    assertEquals("Testing fraction getter", 0.01D, oxygenMolecule.getFraction());
    assertFalse("Testing isActive getter", oxygenMolecule.isActive());
    assertEquals("Test velocities", 88.30259674475872D, oxygenMolecule.getVelocity());
    assertEquals("Testing accretion probability", 3.3087365514550065E-4, oxygenMolecule
        .getAccretionProbability());
    sum += oxygenMolecule.getAccretionProbability();

    // <atom>
    // <name>C</name>
    // <amu>12.011</amu>
    // <abundance>1.4E-4</abundance>
    // <fraction>0.03</fraction>
    // <type>active</type>
    // </atom>
    Atom carbon = (Atom) cloudPopulation.getSpecie("C");
    assertEquals("Testing amu getter", 12.011D, carbon.getAmu());
    assertEquals("Testing abundance getter", 1.4E-4, carbon.getAbundance());
    assertEquals("Testing fraction getter", 0.03D, carbon.getFraction());
    assertTrue("Testing isActive getter", carbon.isActive());
    assertEquals("Test velocities", 144.1314915231989D, carbon.getVelocity());
    assertEquals("Testing accretion probability", 0.0011108134954437967, carbon
        .getAccretionProbability());
    sum += carbon.getAccretionProbability();

    // <molecule>
    // <name>CO</name>
    // <amu>28.000</amu>
    // <abundance>1.4E-4</abundance>
    // <fraction>0.97</fraction>
    // <type>passive</type>
    // </molecule>
    Molecule carbonMolecule = (Molecule) cloudPopulation.getSpecie("CO");
    assertEquals("Testing amu getter", 28.0D, carbonMolecule.getAmu());
    assertEquals("Testing abundance getter", 1.4E-4, carbonMolecule.getAbundance());
    assertEquals("Testing fraction getter", 0.97D, carbonMolecule.getFraction());
    assertFalse("Testing isActive getter", carbonMolecule.isActive());
    assertEquals("Test velocities", 94.39944668038486D, carbonMolecule.getVelocity());
    assertEquals("Testing accretion probability", 0.023523513813675498, carbonMolecule
        .getAccretionProbability());
    sum += carbonMolecule.getAccretionProbability();

    // <atom>
    // <name>N</name>
    // <amu>14.000</amu>
    // <abundance>7.5E-5</abundance>
    // <fraction>0.05</fraction>
    // <fraction_of>N2</fraction_of>
    // <type>active</type>
    // </atom>
    Atom nitrogen = (Atom) cloudPopulation.getSpecie("N");
    assertEquals("Testing amu getter", 14D, nitrogen.getAmu());
    assertEquals("Testing abundance getter", 7.5E-5D, nitrogen.getAbundance());
    assertEquals("Testing fraction getter", 5E-2D, nitrogen.getFraction());
    assertTrue("Testing isActive getter", nitrogen.isActive());
    assertEquals("Test velocities", 133.5009777759161D, nitrogen.getVelocity());
    assertEquals("Testing accretion probability", 9.186470619469092E-4, nitrogen
        .getAccretionProbability());
    sum += nitrogen.getAccretionProbability();

    // <molecule>
    // <name>N2</name>
    // <amu>28.000</amu>
    // <abundance></abundance>
    // <fraction>0.95</fraction>
    // <type>passive</type>
    // </molecule>
    Molecule nitrogenMolecule = (Molecule) cloudPopulation.getSpecie("N2");
    assertEquals("Testing amu getter", 28D, nitrogenMolecule.getAmu());
    // assertEquals("Testing abundance getter", , nitrogenMolecule.getAbundance());
    assertEquals("Testing fraction getter", 0.95D, nitrogenMolecule.getFraction());
    assertNull("Testing fractionOf getter", nitrogenMolecule.getFractionOf());
    assertFalse("Testing isActive getter", nitrogenMolecule.isActive());
    assertEquals("Test velocities", 94.39944668038486D, nitrogenMolecule.getVelocity());
    assertEquals("Testing accretion probability", 0.006171024886687699, nitrogenMolecule
        .getAccretionProbability());
    sum += nitrogenMolecule.getAccretionProbability();

    assertEquals("Testing probabilities sum", 0.9999999999999997, sum);
  }
}
